#include <iostream>
#include <ctime>
#include <vector>
#include <pthread.h>
#include "RingQueue.hpp"
#define PLATESIZE 10
#define PRODUCERSIZE 5
#define PRODUCTION_NUM 10
#define CONSUMERSIZE 4

RingQueue<int> plate(PLATESIZE);

void* producer(void* args)
{
    std::string* name = static_cast<std::string*>(args);
    for(int i = 0; i < PRODUCTION_NUM; i++)
    {
        int weight = rand() % 9 + 1;
        plate.push(weight);
        printf("[生产者%s]向盘中放入一个重%dkg的苹果\n", name->c_str(), weight);
    }
    printf("[生产者%s]退出...\n", name->c_str());
    return nullptr;
}

void* consumer(void* args)
{
    std::string* name = static_cast<std::string*>(args);
    while(true)
    {
        int weight = plate.pop();
        if(weight == 0)
            break;
        printf("[消费者%s]从盘中取出一个重%dkg的苹果\n", name->c_str(), weight);
    }
    printf("[消费者%s]退出...\n", name->c_str());
    return nullptr;
}

int main()
{
    srand((unsigned int)time(nullptr));

    std::vector<std::pair<pthread_t, std::string>> producers(PRODUCERSIZE);
    for(int i = 0; i < PRODUCERSIZE; i++)
    {
        producers[i].second = "producer-" + std::to_string(i);
        pthread_create(&producers[i].first, nullptr, producer, &producers[i].second);
    }
    std::vector<std::pair<pthread_t, std::string>> consumers(CONSUMERSIZE);
    for(int i = 0; i < CONSUMERSIZE; i++)
    {
        consumers[i].second = "consumer-" + std::to_string(i);
        pthread_create(&consumers[i].first, nullptr, consumer, &consumers[i].second);
    }

    for(auto& pr : producers)
        pthread_join(pr.first, nullptr);
    
    for(int i = 0; i < CONSUMERSIZE; i++)
        plate.push(0);
    for(auto& pr : consumers)
        pthread_join(pr.first, nullptr);

    return 0;
}